﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using Space.Library;
using Space.Library.Extensions;
using Space.Model.Data;
using Space.Model.Fsm;

namespace Space.Model.Entity
{
    public class Ship : EntityBase, IPaint
    {
        private bool _isSelected;
        public ShipFsm Fsm { get; set; }
        public ShipModel ShipModel { get; private set; }

        public List<EffectBase> Effects { get; set; } 

        public Point BoardCoords { get; private set; }

        /// <summary>
        /// X,Y pixel coords of center of board square.
        /// </summary>
        public Vector2D Pos { get; private set; }

        public float Orientation { get; private set; }

        public Ship(ShipModel shipModel, Point boardCoords, float orientation)
        {
            Orientation = orientation;
            ShipModel = shipModel;
            Fsm = new ShipFsm(this);
            BoardCoords = boardCoords;
            Pos = boardCoords.AsVectorToMid();
            Effects = new List<EffectBase>();

        }

        public override void Init(GameRunner runner)
        {
            base.Init(runner);
        }

        public void Paint(Painter painter, GameRunner runner)
        {
            painter.DrawShip(this);

            foreach (var effect in Effects)
            {
                effect.Paint(painter, runner);
            }
        }

        public override void Tick(GameRunner runner, int timestep)
        {
            base.Tick(runner, timestep);
            DoAssertions(runner);

            if (Fsm != null)
                Fsm.Update(timestep);
        }

        public override void Cleanup(GameRunner runner)
        {
            base.Cleanup(runner);
        }

        public void DoAssertions(GameRunner runner)
        {
            Debug.Assert(BoardCoords.X < Board.BoardXMax, "Ship outside board (X > MaxX)");
            Debug.Assert(BoardCoords.Y < Board.BoardYMax, "Ship outside board (Y > MaxY)");
        }

        public void Move(Vector2D movement)
        {
            Pos = Pos + movement;
            BoardCoords = Board.GetBoardCoords(Pos);
        }

        public void SetPosition(Point location)
        {
            BoardCoords = location;
            Pos = Board.GetShipPos(location);
        }

        public void Rotate(float value)
        {
            var result = Orientation + value;

            if (result > 360)
                Orientation = result - 360;
            else if (result < 0)

                Orientation = result + 360;
            else
                Orientation = result;
        }

        public bool IsSelected
        {
            get { return _isSelected; }
            set
            {
                GameRunner.Instance.SelectedEntity = value ? this : null;
                _isSelected = value;
            }
        }
    }
}
